package com.quectel.grid.controller;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.quectel.sys.module.sys.service.SysGroupService;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.Response;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.Date;

import static com.quectel.constant.global.StatisticsConstants.*;

public class BaseController {
    @Autowired
    protected HttpServletRequest httpServletRequest;

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @DubboReference
    private SysGroupService sysGroupService;

    /**
     * 检验时间范围
     *
     * @param unitType  DAY,MONTH,HOUR 默认为DAY
     * @param startTime 包含yyyy-MM-dd HH:mm:ss
     * @param endTime   包含yyyy-MM-dd HH:mm:ss
     * @param limit     显示时间根据事件单位传入即可 null默认各个单位下的默认值 HOUR 24 DAY 14  YEAR 1
     * @return
     */
    public Response<Object> checkTimeRange(String unitType, String startTime, String endTime, Integer limit) {
        if (unitType == null) {
            unitType = TIME_RANGE_BY_DAY;
        }
        if (TIME_RANGE_BY_HOUR.equals(unitType)) {
            Date startDate = DateUtils.parse(startTime, DateUtils.FormatType.COMMON);
            Date endDate = DateUtils.parse(endTime, DateUtils.FormatType.COMMON);
            int l = (limit == null ? DEFAULT_HOUR_LIMIT : limit);
            long betweenHour = DateUtil.between(DateUtil.beginOfHour(startDate), DateUtil.endOfHour(endDate), DateUnit.HOUR, true);
            if (betweenHour > l) {
                return Response.error("日期超出最大限定，最大范围:" + l + "小时");
            }
        }
        if (TIME_RANGE_BY_DAY.equals(unitType)) {
            Date startDate = DateUtils.parse(startTime, DateUtils.FormatType.SIMPLE);
            Date endDate = DateUtils.parse(endTime, DateUtils.FormatType.SIMPLE);
            int l = (limit == null ? DEFAULT_DAY_LIMIT : limit);
            long betweenDay = DateUtil.betweenDay(DateUtil.beginOfDay(startDate), DateUtil.endOfDay(endDate), true);
            if (betweenDay > l) {
                return Response.error("日期超出最大限定，最大范围:" + l + "天");
            }
        }
        if (TIME_RANGE_BY_MONTH.equals(unitType)) {

            Date startDate = DateUtils.parse(startTime, DateUtils.FormatType.MONTH);
            Date endDate = DateUtils.parse(endTime, DateUtils.FormatType.MONTH);
            // 按月统计校验
            int l = (limit == null ? DEFAULT_MONTH_LIMIT : limit);
            long betweenMonth = DateUtil.betweenMonth(DateUtil.beginOfMonth(startDate), DateUtil.endOfMonth(endDate), true);
            if (betweenMonth > l) {
                return Response.error("日期超出最大限定，最大范围:" + l + "月");
            }
        }
        return Response.ok();
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Response<Object> handleException(Exception e) {
        logger.error("BaseController报警", e);
        if (e instanceof MethodArgumentNotValidException) {
            //post参数校验出错
            BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
            //咱们找其中之一就可以
            if (bindingResult.getFieldError() != null) {
                return Response.error("数据校验不通过");
            }
            return Response.error("校验错误");
        }
        if (e instanceof ConstraintViolationException) {
            //get参数出错
            return Response.error(e.getLocalizedMessage());
        }
        if (e instanceof MethodArgumentTypeMismatchException) {
            //get 参数类型不匹配
            return Response.error("非法的查询参数");
        }
        if (e instanceof RpcException) {
            //dubbo服务者不可用
            return Response.error("服务正在重启，请稍后");
        }

        return Response.customize(500, "服务器好像出了点小问题");
    }

}
